(function(){

/*
 * 这是最简单的javascript股票账户模拟.
 * 为了兼容javascript的各种版本,没有用class,解包,let之类的新特性.
 *
 * 根据示例 var myAccount 新建账户对象,
 * 根据示例 var myHistroy 新建投资操作历史表(其中'date'暂未使用,只做记录),
 * 运行runAccount()方法模拟投资历史,计算出账户的最后情况
 * 运行account2String()方法把账户的主要信息转换成字符串,方便显示
 * 最后更新日期: 2020-07-07 08:04
 */

/* 账户对象 */
var myAccount = {
  'money': 100.0*10000, // 现金
  'targets': {},  // 标的持有表
  'feeRate_Stock': 1.6/10000, // 股票佣金率
  'feeRate_Fund': 1.0/10000, // 基金债券佣金率
  'minFee_Stock': 5.0, // 股票每次最低佣金
  'minFee_Fund': 0.1, // 基金债券每次最低佣金
  'taxRate': 1.0/1000  // 印花税税率
};

/* 投资操作历史表 */
// 'fee'是可选项,指定费用(含印花税)则不再另外计算,适合特殊情况
// 'type'中只有buy(不分大小写)是买入,其他统一认定为卖出
var myHistroy = [
  {'type': 'buy', 'target': '600000', 'number': 10000, 'price': 10.00, 'date': '2019-05-23'},
  {'type': 'sell', 'target': '600000', 'number': 10000, 'price': 10.00, 'date': '2019-05-24'},
  {'type': 'buy', 'target': '600001', 'number': 11100, 'price': 12.00, 'date': '2019-05-23'},
  {'type': 'buy', 'target': '600002', 'number': 20000, 'price': 14.00, 'date': '2019-05-24'},
  {'type': 'buy', 'target': '512690', 'number': 100000, 'price': 1.8, 'date': '2020-04-24', 'fee': 20.0}
];

/* 把账户信息转换成字符串,方便显示 */
function account2String(account){
  var money = Math.round(account['money']*100)/100;
  var strList = ['--- 现金 ---', money, '--- 持仓 ---'];
  var targets = account['targets'];
  for (target in targets) {
    var number = targets[target];
    if (number == 0) {continue;}
    strList.push(target+' : '+number);
  }
  return strList.join('\n');
}

/* 对账户历史进行运算,修改账户信息,得到投资结果 */
function runAccount(account, histroy){
  for (var i = 0;i < histroy.length;i++){
    // 对单条历史进行处理准备
    var type = histroy[i]['type'];
    var target = histroy[i]['target'];
    var number = histroy[i]['number'];
    var price = histroy[i]['price'];
    var date = histroy[i]['date']; 
    type = type.toLowerCase();
    if (!(target in account['targets']))  account['targets'][target] = 0;
    // 准备完毕,开始计算
    var deal = number*price; // 成交额
    var fee = 0; // 佣金
    // 如果有手动指定佣金(包括印花税),则不需要计算,否则分类,基金与股票两种类型
    if ('fee' in histroy[i]){
      fee = histroy[i]['fee'];
    }else{
      // 分类计算佣金,51开头是基金债券,其他是股票
      if ((target[0] == '5' || target[0] == '1')){
        fee = deal*account['feeRate_Fund'];
        if (fee < account['minFee_Fund']) {fee = account['minFee_Fund']}
      }else{
        fee = deal*account['feeRate_Stock'];
        if (fee < account['minFee_Stock']) {fee = account['minFee_Stock']}
        // 股票卖出时计算印花税
        if (type != 'buy'){
          fee += deal*account['taxRate'];
        }
      }
    }
    if (type == 'buy'){
      account['money'] -= (deal+fee); 
      account['targets'][target] += number;
    }else{
      account['money'] += (deal-fee);
      account['targets'][target] -= number;
    }
  }
  return account;
}

/* 模拟计算与显示 */
runAccount(myAccount, myHistroy); // 模拟投资历史
myAccount['money'] += 0.0; // 资金额外修正,例如分红,部分标的免税时,需要额外修正一下
var message = account2String(myAccount); // 最终显示的信息
if(console){
  console.log(message);
}
return message;

})();